package com.etc

import org.apache.spark.sql.{Dataset, RowFactory, SparkSession}


import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}

/**
 * TF-IDF  是一种简单的文本特征提取算法
 *  词频(Term Frequency): 某个关键词在文本中出现的次数
 *  逆文档频率(Inverse Document Frequency): 大小与一个词的常见程度成反比
 *  TF = 某个词在文章中出现的次数/文章的总词数
 *  IDF = log(查找的文章总数　/ (包含该词的文章数　+ 1))
 *  TF-IDF = TF(词频)　x IDF(逆文档频率)
 *  此处未考虑去除停用词(辅助词，如副词，介词等)和
 *  语义重构("数据挖掘"，＂数据结构＂，拆分成＂数据＂，＂挖掘＂，＂数据＂，＂结构＂)
 *  这样两个完全不同的文本具有　50% 的相似性，是非常严重的错误．
 * Created by eric on 16-7-24.
 */
object TFIDF {

  def main(args: Array[String]): Unit = {


    val spark = SparkSession.builder()
      .master("local[*]")
      .appName("tfidf")
      .getOrCreate()

    val sentenceData = spark.createDataFrame(Seq(
      (0.0, "Hi I heard about Spark"),
      (0.0, "I wish Java could use case classes"),
      (1.0, "Logistic regression models are neat")
    )).toDF("label", "sentence")


    //使用Tokenizer来将句子分割成单词
    val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
    val wordsData = tokenizer.transform(sentenceData)

    //使用HashingTF将句子中的单词哈希成特征向量（这个可以在前一章节的最后输出打印截图中看到具体的值）
    val hashingTF = new HashingTF()
      .setInputCol("words").setOutputCol("rawFeatures").setNumFeatures(20)

    val featurizedData = hashingTF.transform(wordsData)



    // alternatively, CountVectorizer can also be used to get term frequency vectors

    //使用IDF对上面产生的特征向量进行rescale
    val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")

    val idfModel = idf.fit(featurizedData)

    val rescaledData = idfModel.transform(featurizedData)

    rescaledData.foreach(x => println(x))


    //最后得到的特征向量可以作为其他机器学习算法的输入
  }
}
